﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Text;
using System.Data;
using Newtonsoft.Json;
using System.Text.RegularExpressions;

namespace XMK.Utils
{
    /// <summary>
    /// JSON对象操作工具
    /// </summary>
    public sealed class JsonHelper
    {
        #region json字符首字母大小写转换处理
        /// <summary>
        /// 将json字符转换成Java的json字符串(首字母小写)
        /// </summary>
        /// <param name="jsonStr"></param>
        /// <returns></returns>
        public static string ConvertJavaJsonString(string jsonStr)
        {
            return ModifyFirstAlpha(jsonStr, 0);
        }
        /// <summary>
        /// 将用友的json字符转换成.net正常的格式(首字母大写)
        /// </summary>
        /// <param name="jsonStr"></param>
        /// <returns></returns>
        public static string ConvertNetJsonString(string jsonStr)
        {
            return ModifyFirstAlpha(jsonStr, 1);
        }
        /// <summary>
        /// 大小写互换
        /// </summary>
        /// <param name="str">要转换的字符串</param>
        /// <param name="alpha">alpha的值为toupper时转换为大写，为tolower时转换为小写</param>
        /// <returns></returns>
        static string ModifyFirstAlpha(string str, int alpha)
        {
            string regStr = "";
            if (alpha == 1)
            {
                //转义后的正则表达式字符串
                regStr = "['|\"][a-z](?=[a-zA-Z_]*\\\\?['|\"]:)";    //原正则表达式   ['|"][a-z](?=[a-zA-Z_]*\\?['|"]:)        
                str = Regex.Replace(str, regStr, CapTextToUpper);
            }
            else //if (alpha.ToUpper() == "TOLOWER")
            {
                //转义后的正则表达式字符串
                regStr = "['|\"][A-Z](?=[a-zA-Z_]*\\\\?['|\"]:)";    //原正则表达式   ['|"][A-Z](?=[a-zA-Z_]*\\?['|"]:)             
                str = Regex.Replace(str, regStr, CapTextToLower);
            }
            return str;
        }

        //要替换的字符串委托函数(小写转大写)
        static string CapTextToUpper(Match m)
        {
            string x = m.ToString();
            if (x.Length <= 1)
                return x.ToUpper();
            if (char.IsLower(x[x.Length - 1]))
            {
                return x.Substring(0, x.Length - 1) + char.ToUpper(x[x.Length - 1]).ToString();
            }
            return x;
        }

        //要替换的字符串委托函数(大写转小写)
        static string CapTextToLower(Match m)
        {
            string x = m.ToString();
            if (x.Length <= 1)
                return x.ToLower();
            if (char.IsUpper(x[x.Length - 1]))
            {
                return x.Substring(0, x.Length - 1) + char.ToLower(x[x.Length - 1]).ToString();
            }
            return x;
        }
        #endregion

        #region 私有成员

        private const string JSON_FORMAT = "\"{0}\":{1},";

        #endregion

        #region 公共方法

        /// <summary>
        /// 将对象转换成JSON格式数据，不支持值类型直接传入
        /// </summary>
        /// <param name="obj">需要转换的对象</param>
        /// <returns>json格式的对象</returns>
        public static string ToJson(object obj)
        {
            if (obj == null)
                return "null";

            Type type = obj.GetType();

            if (type == typeof(DataTable))
            {
                return ToJson((obj as DataTable));
            }
            else if (type == typeof(DataSet))
            {
                return ToJson((obj as DataSet));
            }
            else
            {
              return   JsonConvert.SerializeObject(obj);
               // return JavaScriptConvert.SerializeObject(obj);
            }
        }

        /// <summary>
        /// 对象根据属性列表转化Json,不支持值类型直接传入
        /// </summary>
        /// <param name="obj">需要转换的对象</param>
        /// <param name="propertyNames">属性名</param>
        /// <returns>json格式的对象</returns>
        public static string ToJson(object obj, string[] propertyNames)
        {
            if (obj == null)
                return "null";
            if (propertyNames.Length == 0)
                return ToJson(obj);
            Type objType = obj.GetType();
            PropertyInfo info;
            StringBuilder sb = new StringBuilder();
            sb.Append("[{");
            foreach (string propertyName in propertyNames)
            {
                info = objType.GetProperty(propertyName);
                if (info != null)
                    sb.Append(string.Format(JSON_FORMAT, info.Name, GetValue(obj, info)));
            }
            if (sb.Length > 1)
                sb.Remove(sb.Length - 1, 1);
            sb.Append("}]");
            return sb.ToString();
        } 
        
        /// <summary>  
        /// DataSet转换成Json格式  
        /// </summary>  
        /// <param name="dsSource">DataSet数据源</param>  
        /// <returns></returns>  
        public static string ToJson(DataSet dsSource)
        {
            StringBuilder jsonResult = new StringBuilder();

            if (dsSource != null && dsSource.Tables.Count > 0)
            {
                jsonResult.Append("{");

                for (int index = 0; index < dsSource.Tables.Count; index++)
                {
                    jsonResult.Append("\"");
                    jsonResult.Append(dsSource.Tables[index].TableName);
                    jsonResult.Append("\":");
                    jsonResult.Append(ToJson(dsSource.Tables[index]));

                    if (index != dsSource.Tables.Count - 1)
                    {
                        jsonResult.Append(",");
                    }
                }
                jsonResult.Append("}");
            }
            return jsonResult.ToString();
        }
        
        /// <summary>  
        /// DataTable转换成Json格式  
        /// </summary>  
        /// <param name="dtSource">DataTable数据源</param>  
        /// <returns>json格式的数据表</returns>  
        public static string ToJson(DataTable dtSource)
        {
            if (dtSource == null || dtSource.Rows.Count == 0) return string.Empty;

            StringBuilder jsonBuilder = new StringBuilder();

            for (int rowIndex = 0; rowIndex < dtSource.Rows.Count; rowIndex++)
            {
                if (rowIndex == 0)
                {
                    jsonBuilder.Append("[");
                }

                jsonBuilder.Append("{");

                for (int columnsIndex = 0; columnsIndex < dtSource.Columns.Count; columnsIndex++)
                {
                    jsonBuilder.Append("\"");
                    jsonBuilder.Append(dtSource.Columns[columnsIndex].ColumnName);
                    string itemContent = dtSource.Rows[rowIndex][columnsIndex].ToString().Replace("\"", "\\\"").Replace("\r\n", "\\r\\n");

                    if (dtSource.Columns[columnsIndex].DataType == Type.GetType("System.Int32"))
                    {
                        jsonBuilder.Append("\":");
                        jsonBuilder.Append(itemContent);
                        jsonBuilder.Append(",");
                    }
                    else
                    {
                        jsonBuilder.Append("\":\"");
                        jsonBuilder.Append(itemContent);
                        jsonBuilder.Append("\",");
                    }
                }

                jsonBuilder.Remove(jsonBuilder.Length - 1, 1);
                jsonBuilder.Append("},");

            }

            jsonBuilder.Remove(jsonBuilder.Length - 1, 1);
            jsonBuilder.Append("]");

            return jsonBuilder.ToString();

        }

        /// <summary>
        /// 将JSON字符串反序列化成对象
        /// </summary>
        /// <param name="value">要反序列化的JSON字符串</param>
        /// <returns>对象</returns>
        public static object FromJson(string value)
        {
            return JsonConvert.DeserializeObject(value);
            //return JavaScriptConvert.DeserializeObject(value);
        }

        /// <summary>
        /// 将JSON字符串反序列化成对象
        /// </summary>
        /// <param name="value">要反序列化的JSON字符串</param>
        /// <param name="type">类型</param>
        /// <returns>传入类型的对象</returns>
        public static object FromJson(string value, Type type)
        {
            return JsonConvert.DeserializeObject(value, type);
            //return JavaScriptConvert.DeserializeObject(value, type);
        }

        /// <summary>
        /// 将JSON字符串反序列化成对象,注意：对象必须有无参数的构造函数，否则会丢出异常
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="jsonString">要反序列化的JSON字符串</param>
        /// <returns>反序列化的结果对象</returns>
        public static T FromJson<T>(string jsonString) where T : new()
        {
            if (string.IsNullOrEmpty(jsonString))
                return new T();
            return JsonConvert.DeserializeObject<T>(jsonString,new JsonSerializerSettings()
            {
                NullValueHandling = NullValueHandling.Ignore
            });
           // return JavaScriptConvert.DeserializeObject<T>(jsonString);
        }
        /// <summary>
        /// 使用微软自带的将JSON字符串反序列化成对象,针对非list对象进行解析，速度快
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="jsonString">要反序列化的JSON字符串</param>
        /// <returns>反序列化的结果对象</returns>
        public static T FromJsonMs<T>(string jsonString) where T : new()
        {
            System.Web.Script.Serialization.JavaScriptSerializer jsonconvert = new System.Web.Script.Serialization.JavaScriptSerializer();
            return jsonconvert.Deserialize<T>(jsonString);
        }

        /// <summary>
        /// 将JSON字符串反序列化成对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="jsonString">要反序列化的JSON字符串</param>
        /// <returns>反序列化的结果对象</returns>
        public static T ObjectFromJson<T>(string jsonString)
        {
            if (string.IsNullOrEmpty(jsonString))
            {
                throw new Exception("The content is not empty!");
            }
            return JsonConvert.DeserializeObject<T>(jsonString, new JsonSerializerSettings()
            {
                NullValueHandling = NullValueHandling.Ignore
            });
            //return JavaScriptConvert.DeserializeObject<T>(jsonString);
        }

        #endregion

        #region 私有方法

        /// <summary>
        /// 获取对象的属性值
        /// </summary>
        /// <param name="obj">对象</param>
        /// <param name="propertyInfo">属性信息</param>
        /// <returns>属性值</returns>
        private static string GetValue(object obj, PropertyInfo propertyInfo)
        {
            object value = propertyInfo.GetValue(obj, null);
            StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
            JsonWriter jw = new JsonTextWriter(sw);
            JsonSerializer serializer = new JsonSerializer();
            if (value is IConvertible)
                sw.Write(JsonConvert.ToString(value));
            //sw.Write(JavaScriptConvert.ToString(value));
            else
                serializer.Serialize(jw, value);
            return sw.ToString();
        }
        #endregion
    }

}
